package restaurant;

import java.util.ArrayList;
import java.util.Date;

/**
 * The Invoker class is used to call the command objects associated with the
 * system's functionality.
 * 
 * @author Odessa
 */

public class Invoker
{

	/** The information stored in the system. */
	private InformationAggregator info;

	/** The command to execute. */
	private Command command;

	/** The result of the executed command. */
	private Object result;



	/**
	 * Instantiates the invoker.
	 */
	public Invoker() {
		info = InformationAggregator.getInstance();
	}



	/**
	 * Executes the command.
	 * 
	 * @return the result of executing the command.
	 */
	private Object process()
	{
		return command.execute();
	}



	/**
	 * Acknowledges a service request.
	 * 
	 * @param waitID the waitperson who acknowledges the request.
	 * @param tableNo the table whose request is being acknowledged.
	 */
	public void acknowledgeRequest(int waitID, int tableNo)
	{
		command = new cmdAcknowledgeRequest(waitID, tableNo);
		result = process();
	}



	/**
	 * Activates a table.
	 * 
	 * @param tableNo the table to activate.
	 * @param pin the pin to activate the table.
	 * @return {@code true} if the table was successfully activated.
	 */
	public boolean activateTable(int tableNo, int pin)
	{
		command = new cmdActivateTable(info, tableNo, pin);
		result = process();

		return (Boolean) result;
	}



	/**
	 * Creates a new comment.
	 * 
	 * @param comment the comment.
	 * @return the newly created comment.
	 */
	public Comment createComment(String comment)
	{
		command = new cmdAddComment(info, comment);
		result = process();

		return (Comment) result;
	}



	/**
	 * Creates a new menu item.
	 * 
	 * @param name the menu item name.
	 * @param description the description of the item.
	 * @param price the price of the item.
	 * @param prepTime the time to prepare the item.
	 * @param course the item's course.
	 * @param vegetarian whether or not this item is vegetarian.
	 * @return the newly created menu item.
	 */
	public MenuItem createMenuItem(String name, String description,
			double price, int prepTime, String course, boolean vegetarian)
	{
		command = new cmdAddMenuItem(info, name, description, price, prepTime,
				course, vegetarian);
		result = process();

		return (MenuItem) result;
	}



	/**
	 * Creates a new offer.
	 * 
	 * @param startDate the start date of the offer.
	 * @param endDate the end date of the offer.
	 * @param description the description of the offer.
	 * @param discount the discount of the offer.
	 * @return the newly created offer.
	 */
	public Offer createOffer(Date startDate, Date endDate, String description,
			double discount)
	{
		command = new cmdAddOffer(info, startDate, endDate, description,
				discount);
		result = process();

		return (Offer) result;
	}



	/**
	 * Deletes an offer.
	 * 
	 * @param offerNo the offer being deleted.
	 */
	public void deleteOffer(int offerNo)
	{
		command = new cmdDeleteOffer(info, offerNo);
		result = process();
	}



	/**
	 * Gets the available tables.
	 * 
	 * @return the available tables.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Table> getAvailableTables()
	{
		command = new cmdAvailableTables(info);
		result = process();

		return (ArrayList<Table>) result;
	}



	/**
	 * Gets the average pick up time.
	 * 
	 * @param waitperson the waitperson.
	 * @return the average pick up time.
	 */
	public float getAvgPickUpTime(int waitperson)
	{
		command = new cmdAveragePickUpTime(info, waitperson);
		result = process();

		return (Float) result;
	}



	/**
	 * Gets the comments.
	 * 
	 * @return the comments.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Comment> getComments()
	{
		command = new cmdGetComments(info);
		result = process();

		return (ArrayList<Comment>) result;
	}



	/**
	 * Gets the customer wait queue. This returns the list of customers
	 * currently waiting to be seated at a table.
	 * 
	 * @return the customer wait queue.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Customer> getCustomerWaitQueue()
	{
		command = new cmdCustomerWaitQueue(info);
		result = process();

		return (ArrayList<Customer>) result;
	}



	/**
	 * Gets the gross sales for a day.
	 * 
	 * @param day the day to view the sales for.
	 * @return the gross sales for this day.
	 */
	public String getGrossSales(Date day)
	{
		command = new cmdGrossSalesForDay(info, day);
		result = process();

		return (String) result;
	}



	/**
	 * Gets the gross sales for a period.
	 * 
	 * @param start the start date of the period.
	 * @param end the end date of the period.
	 * @return the gross sales for this period.
	 */
	public String getGrossSales(Date start, Date end)
	{
		command = new cmdGrossSalesForPeriod(info, start, end);
		result = process();

		return (String) result;
	}



	/**
	 * Gets the items sold for a day.
	 * 
	 * @param day the day to view the items sold for.
	 * @return the items sold for a day.
	 */
	public String getItemsSold(Date day)
	{
		command = new cmdItemsSoldForDay(info, day);
		result = process();

		return (String) result;
	}



	/**
	 * Gets the items sold for a period.
	 * 
	 * @param start the start date of the period.
	 * @param end the end date of the period.
	 * @return the items sold for a period.
	 */
	public String getItemsSold(Date start, Date end)
	{
		command = new cmdItemsSoldForPeriod(info, start, end);
		result = process();

		return (String) result;
	}



	/**
	 * Gets the kitchen queue. Returns the list of orders waiting to be prepared
	 * by the kitchen staff.
	 * 
	 * @return the kitchen queue.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Order> getKitchenQueue()
	{
		command = new cmdKitchenQueue(info);
		result = process();

		return (ArrayList<Order>) result;
	}



	/**
	 * Gets the entire menu. The menu returned will contain all the menu items.
	 * 
	 * @return the entire menu.
	 */
	public Menu getMenu()
	{
		command = new cmdMenu(info);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the menu by course. The menu returned will contain only items in the
	 * <code>course</code> entered.
	 * 
	 * @param course the course by which to view the menu.
	 * @return the menu containing only items in the {@code course) entered.
	 * 
	 */
	public Menu getMenuByCourse(String course)
	{
		command = new cmdMenuByCourse(info, course);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the menu by a preparation time. The menu returned will contain items
	 * with preparation times lower than the {@code prepTime} entered.
	 * 
	 * @param prepTime the preparation time by which to view the menu.
	 * @return the menu based on the {@code prepTime} entered.
	 */
	public Menu getMenuByPrepTime(int prepTime)
	{
		command = new cmdMenuByPrepTime(info, prepTime);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the menu by price. The menu returned will contain items with prices
	 * lower than the {@code price} entered.
	 * 
	 * @param price the price by which to view the menu.
	 * @return the menu based on the {@code price} entered.
	 */
	public Menu getMenuByPrice(int price)
	{
		command = new cmdMenuByPrice(info, price);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the menu by item ratings. The menu returned will contain items with
	 * ratings higher than the {@code rating} entered.
	 * 
	 * @param rating the rating by which to view the menu.
	 * @return the menu based on the {@code rating} entered.
	 */
	public Menu getMenuByRating(int rating)
	{
		command = new cmdMenuByRating(info, rating);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the menu by vegetarian items. The menu returned will contain only
	 * vegetarian items.
	 * 
	 * @return the menu with only vegetarian items.
	 */
	public Menu getMenuByVegetarian()
	{
		command = new cmdMenuByVegetarian(info);
		result = process();

		return (Menu) result;
	}



	/**
	 * Gets the offers.
	 * 
	 * @return the offers.
	 */
	public SpecialOffers getOffers()
	{
		command = new cmdGetOffers(info);
		result = process();

		return (SpecialOffers) result;
	}



	/**
	 * Gets the orders.
	 * 
	 * @return the orders.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Order> getOrders()
	{
		command = new cmdGetOrders(info);
		result = process();

		return (ArrayList<Order>) result;
	}



	/**
	 * Gets the ratings for a menu item.
	 * 
	 * @param itemNo the item to view the ratings for.
	 * @return the ratings of this item.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Comment> getRatings(int itemNo)
	{
		command = new cmdGetRatings(info, itemNo);
		result = process();

		return (ArrayList<Comment>) result;
	}



	/**
	 * Gets a table's tab.
	 * 
	 * @param tableNo the table to view the tab for.
	 * @return the tab for this table.
	 */
	public Tab getTab(int tableNo)
	{
		command = new cmdGetTab(info, tableNo);
		result = process();

		return (Tab) result;
	}



	/**
	 * Gets the occupied tables.
	 * 
	 * @return the occupied tables.
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Table> getAssignedTables()
	{
		command = new cmdAssignedTables(info);
		result = process();

		return (ArrayList<Table>) result;
	}



	/**
	 * Gets the tables waiting on their order to be delivered.
	 * 
	 * @return the tables waiting on their order to be delivered
	 */
	@SuppressWarnings("unchecked")
	public ArrayList<Table> getWaitingTables()
	{
		command = new cmdWaitingTables(info);
		result = process();

		return (ArrayList<Table>) result;
	}



	/**
	 * Sets an item's availability.
	 * 
	 * @param itemNo the item number of the item.
	 * @param numAvailable the number of the item available.
	 */
	public void itemAvailability(int itemNo, int numAvailable)
	{
		command = new cmdItemAvailability(info, itemNo, numAvailable);
		result = process();
	}



	/**
	 * Indicates an item as being ready for pick up.
	 * 
	 * @param order the order that is ready for pick up.
	 */
	public void itemUp(int order)
	{
		command = new cmdItemUp(info, order);
		result = process();
	}



	/**
	 * Places an order for an item.
	 * 
	 * @param tableNo the table placing the order.
	 * @param itemNo the item being ordered.
	 * @param price the price of the item being ordered.
	 */
	public void orderItem(int tableNo, int itemNo, double price)
	{
		command = new cmdOrderItem(info, tableNo, itemNo, price);
		result = process();
	}



	/**
	 * Indicates an item as being picked up by the waitperson.
	 * 
	 * @param table the table whose order is picked up.
	 */
	public void orderPickup(int table)
	{
		command = new cmdOrderPickup(info, table);
		result = process();
	}



	/**
	 * Pays an opened tab.
	 * 
	 * @param tableNo the table paying the tab.
	 * @param cardNumber the credit card used to pay the tab.
	 * @param expiration the expiration date of the credit card.
	 * @return {@cod true} if the payment was successful.
	 */
	public boolean payTab(int tableNo, String cardNumber, Date expiration)
	{
		command = new cmdPayTab(info, tableNo, cardNumber, expiration);
		result = process();

		return (Boolean) result;
	}



	/**
	 * Submits a menu item rating.
	 * 
	 * @param itemNo the menu item being rated.
	 * @param rating the rating for the item.
	 * @param comment the comment for the item.
	 */
	public void rateItem(int itemNo, int rating, String comment)
	{
		command = new cmdRateItem(info, itemNo, rating, comment);
		result = process();
	}



	/**
	 * Places a request for service.
	 * 
	 * @param tableNo the table requesting service.
	 */
	public void requestService(int tableNo)
	{
		command = new cmdRequestService(info, tableNo);
		result = process();
	}



	/**
	 * Requests a table.
	 * 
	 * @param name the name of the person requesting the table.
	 * @param numPeople the number of people in the party.
	 * @return the pin for the table.
	 */
	public String requestTable(String name, int numPeople)
	{
		command = new cmdRequestTable(info, name, numPeople);
		result = process();

		return (String) result;
	}



	/**
	 * Resets a table.
	 * 
	 * @param tableNo the table number of the table to reset.
	 */
	public void resetTable(int tableNo)
	{
		command = new cmdResetTable(info, tableNo);
		result = process();
	}



	/**
	 * Updates a menu item.
	 * 
	 * @param itemNo the menu item being updated.
	 * @param newName the new name of the item.
	 * @param newDesc the new description of the item.
	 * @param newPrice the new price of the item.
	 * @param newTime the new preparation time of the item.
	 * @param newCourse the new course of the item.
	 * @param newVeg whether or not this item is vegetarian.
	 * @return the updated menu item.
	 */
	public MenuItem updateMenuItem(int itemNo, String newName, String newDesc,
			double newPrice, int newTime, String newCourse, boolean newVeg)
	{
		command = new cmdUpdateMenuItem(info, itemNo, newName, newDesc,
				newPrice, newTime, newCourse, newVeg);
		result = process();

		return (MenuItem) result;
	}



	/**
	 * Updates a special offer.
	 * 
	 * @param offerNo the offer being updated.
	 * @param newStart the new start date of the offer.
	 * @param newEnd the new end date of the offer.
	 * @param newDesc the new description of the offer.
	 * @param newDiscount the new discount provided by the offer.
	 * @return the updated offer.
	 */
	public Offer updateOffer(int offerNo, Date newStart, Date newEnd,
			String newDesc, double newDiscount)
	{
		command = new cmdUpdateOffer(info, offerNo, newStart, newEnd, newDesc,
				newDiscount);
		result = process();

		return (Offer) result;
	}
}
